home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
plan
/
src
/
dayedit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
8KB
|
319 lines
/*
* Handle all the more complicated user interactions with an entry list menu.
* Whenever the user begins editing a row, the entry in that row is copied
* to the edit struct. All editing takes place, until it is confirmed and
* put back into the main list. The reason for this is that entering a new
* date or time doesn't make the row disappear from the current list because
* it now belongs to a different day before editing is finished.
*
* got_entry_press(lw, x, y, on) The user pressed on one of the
* buttons in the list menu button array.
* confirm_new_entry() Puts the currently edited row back
* into the mainlist, and re-sorts.
* undo_new_entry() Kill the edit buffer, undoing the
* changes to the current row.
* got_entry_text(lw, x, y, text) The user entered text into the text
* button. There is never more than one.
* sensitize_edit_buttons() Desensitize all buttons in the
* bottom button row that don't make
* sense at the moment.
*/
#ifndef MIPS
#include <stdlib.h>
#endif
#include <time.h>
#include <Xm/Xm.h>
#include "cal.h"
extern time_t parse_datestring(), parse_timestring();
extern void parse_warnstring();
extern char *mkbuttonstring(), *mkdatestring();
extern char *mystrdup();
extern struct tm *time_to_tm();
extern time_t get_time();
extern struct config config; /* global configuration data */
extern struct list *mainlist; /* list of all schedule entries */
extern int curr_month; /* month being displayed, 0..11 */
extern int curr_year; /* year being displayed, since 1900 */
struct edit edit; /* info about entry being edited */
got_entry_press(lw, x, y, on)
struct listmenu *lw; /* which menu */
int x, y; /* which column/row */
int on; /* enable radio but: on/off */
{
register struct entry *ep; /* affected entry */
int num; /* number of entries so far */
time_t now; /* current time */
num = lw->sublist ? lw->sublist->nentries : 0;
if (y-1 > num) /* illegal entry? */
return;
if (edit.editing && (edit.y != y || edit.menu != lw))
confirm_new_entry();
if (!edit.editing) {
if (y-1 < num)
clone_entry(&edit.entry, lw->sublist->entry[y-1]);
else {
clone_entry(&edit.entry, (struct entry *)0);
now = get_time();
edit.entry.time = lw->time ? lw->time : now - now%60;
}
edit.editing = TRUE;
edit.changed = FALSE;
edit.y = y;
edit.menu = lw;
sensitize_edit_buttons();
}
ep = &edit.entry;
switch(x) {
case SC_ENABLE:
ep->suspended = !on;
edit.changed = TRUE;
sensitize_edit_buttons();
update_all_listmenus();
break;
case SC_TIME:
if (lw->time && !lw->period &&
(!lw->sublist || y > lw->sublist->nentries))
print_button(lw->entry[y][SC_DATE],
mkdatestring(lw->time ? lw->time : now));
edit_list_button(TRUE, lw, x, y);
break;
case SC_LENGTH:
if (ep->notime)
break;
case SC_DATE:
case SC_NOTE:
edit_list_button(TRUE, lw, x, y);
break;
case SC_ADVANCE:
if (ep->notime)
break;
if (config.bigwarning)
edit_list_button(TRUE, lw, x, y);
else
create_advance_popup();
break;
case SC_RECYCLE:
create_recycle_popup();
break;
case SC_MESSAGE:
create_text_popup("Message", &edit.entry.message, x);
break;
case SC_SCRIPT:
if (ep->notime)
break;
create_text_popup("Shell Script", &edit.entry.script, x);
break;
case SC_MEETING:
#if 0 /*<<< not yet implemented */
create_text_popup("Meeting", &edit.entry.meeting, x);
#endif
break;
case SC_PRIVATE:
ep->private ^= TRUE;
edit.changed = TRUE;
sensitize_edit_buttons();
update_all_listmenus();
break;
}
}
/*
* confirm new entry, put it in the list
*/
confirm_new_entry()
{
BOOL changed;
struct tm new;
struct tm old;
edit_list_button(FALSE, edit.menu, 0, 0);
changed = edit.editing && edit.changed;
destroy_text_popup();
destroy_recycle_popup();
destroy_advance_popup();
new = *time_to_tm(edit.entry.time);
old = new;
if (changed) {
mainlist->locked++;
if (!edit.menu->sublist ||
edit.y-1 >= edit.menu->sublist->nentries)
(void)add_entry(&mainlist, &edit.entry);
else {
struct entry *ep = edit.menu->sublist->entry[edit.y-1];
old = *time_to_tm(ep->time);
delete_entry(mainlist, ep - mainlist->entry);
(void)add_entry(&mainlist, &edit.entry);
}
rebuild_repeat_chain(mainlist);
mainlist->locked--;
}
destroy_entry(&edit.entry);
edit.editing = FALSE;
edit.changed = FALSE;
sensitize_edit_buttons();
if (changed) {
update_all_listmenus();
if (old.tm_mday != new.tm_mday &&
old.tm_mon == curr_month && old.tm_year == curr_year)
draw_day_notes(old.tm_mday);
if (new.tm_mon == curr_month && new.tm_year == curr_year)
draw_day_notes(new.tm_mday);
if (old.tm_mday != new.tm_mday)
draw_year_day_notes(old.tm_mday, old.tm_mon,
old.tm_year, FALSE);
draw_year_day_notes(new.tm_mday, new.tm_mon,
new.tm_year, FALSE);
draw_week_day(new.tm_mday, new.tm_mon, new.tm_year);
mainlist->modified = TRUE;
}
}
/*
* undo all editing, restore the entry before we started editing
*/
undo_new_entry()
{
if (edit.editing) {
destroy_text_popup();
destroy_recycle_popup();
destroy_advance_popup();
destroy_entry(&edit.entry);
edit.editing = FALSE;
edit.changed = FALSE;
sensitize_edit_buttons();
draw_list(edit.menu);
}
}
/*
* user entered text into one of the buttons in the entry list
*/
got_entry_text(lw, x, y, text)
struct listmenu *lw; /* which menu */
int x, y; /* which column/row */
char *text; /* text input by user */
{
register struct entry *ep; /* affected entry */
register char *p; /* to remove trailing \n's */
ep = &edit.entry;
switch(x) {
case SC_DATE:
if (*text) {
time_t temp = parse_datestring(text, 0);
if (temp > EON)
ep->time = ep->time % 86400 + temp;
}
edit_list_button(TRUE, lw, SC_TIME, y);
print_button(lw->entry[y][SC_DATE],
mkbuttonstring(lw, SC_DATE, y));
break;
case SC_TIME:
if (*text == '-') {
ep->notime = TRUE;
ep->time -= ep->time % 86400;
} else if (*text) {
ep->notime = FALSE;
ep->time -= ep->time % 86400;
ep->time += parse_timestring(text);
}
edit_list_button(TRUE,lw, ep->notime ? SC_NOTE : SC_LENGTH, y);
print_button(lw->entry[y][SC_TIME],
mkbuttonstring(lw, SC_TIME, y));
break;
case SC_LENGTH: {
time_t length;
while (*text == ' ') text++;
length = *text==0 ? 0 :
*text=='-' ? parse_timestring(text+1) - ep->time%86400
: parse_timestring(text);
if (length < 0)
length = 0;
if (length > 86400)
length = 86400;
ep->length = length;
edit_list_button(TRUE, lw, config.bigwarning && !ep->notime ?
SC_ADVANCE : SC_NOTE, y);
print_button(lw->entry[y][SC_LENGTH],
mkbuttonstring(lw, SC_LENGTH, y));
break; }
case SC_ADVANCE:
parse_warnstring(text, &ep->early_warn, &ep->late_warn,
&ep->noalarm);
edit_list_button(TRUE, lw, SC_NOTE, y);
print_button(lw->entry[y][SC_ADVANCE],
mkbuttonstring(lw, SC_ADVANCE, y));
break;
case SC_NOTE:
if (ep->note)
free(ep->note);
ep->note = 0;
while (*text && (*text == ' ' || *text == '\t'))
text++;
for (p=text+strlen(text)-1; p != text &&
(*p == '\n' || *p == '\t' || *p == ' '); *p-- = 0);
for (p=text; *p; p++)
if (*p == '\n') *p = ' ';
if (*text)
ep->note = mystrdup(text);
edit_list_button(FALSE, lw, 0, 0);
print_button(lw->entry[y][SC_NOTE],
mkbuttonstring(lw, SC_NOTE, y));
XmProcessTraversal(lw->done, XmTRAVERSE_CURRENT);
}
edit.changed = TRUE;
edit.entry.suspended = FALSE;
if (x == SC_NOTE) /* eoln */
confirm_new_entry();
sensitize_edit_buttons();
}
/*
* while a new entry is being edited, it is kept in the <edit> struct,
* which overrides the appropriate entry (if any) in the mainlist. If
* it is being edited, the Confirm button should be sensitive. If it is
* being edited and has been changed, the Undo button should be sensitive.
*/
sensitize_edit_buttons()
{
Arg args;
if (edit.menu) {
XtSetArg(args, XmNsensitive, edit.changed);
XtSetValues(edit.menu->confirm, &args, 1);
XtSetArg(args, XmNsensitive, edit.changed);
XtSetValues(edit.menu->undo, &args, 1);
XtSetArg(args, XmNsensitive, edit.editing);
XtSetValues(edit.menu->dup, &args, 1);
XtSetArg(args, XmNsensitive, edit.editing);
XtSetValues(edit.menu->del, &args, 1);
}
}